package com.vogue.supplymall.order.domain.biz.impl;

import com.vogue.configs.springextend.remote.DelegateResource;
import com.vogue.gear.memory.provider.IMemProvider;
import com.vogue.sprakka.client.future.FutureWrapper;
import com.vogue.supplymall.admin.business.common.constant.CachedPayValues;
import com.vogue.supplymall.admin.business.common.constant.CachedTsPayValues;
import com.vogue.supplymall.admin.business.common.inter.bean.InterCachePayValues;
import com.vogue.supplymall.common.constant.ConstantBean;
import com.vogue.supplymall.common.domain.dto.AlterRefundInfo;
import com.vogue.supplymall.common.domain.dto.OrderDetailInfo;
import com.vogue.supplymall.common.domain.dto.OrderInfo;
import com.vogue.supplymall.common.domain.dto.PayOnlinePaymentDTO;
import com.vogue.supplymall.common.domain.dto.PaymentInfo;
import com.vogue.supplymall.common.domain.dto.UserInfo;
import com.vogue.supplymall.common.domain.tool.MessageSourceUtils;
import com.vogue.supplymall.common.domain.tool.VestUtils;
import com.vogue.supplymall.match.domain.model.MatchOrgan;
import com.vogue.supplymall.match.domain.service.MatchOrganService;
import com.vogue.supplymall.order.domain.biz.OrderUpdateBiz;
import com.vogue.supplymall.order.domain.biz.RefundBiz;
import com.vogue.supplymall.order.domain.model.AccountPrepay;
import com.vogue.supplymall.order.domain.model.AccountPrepayDetail;
import com.vogue.supplymall.order.domain.model.Order;
import com.vogue.supplymall.order.domain.model.OrderBuyer;
import com.vogue.supplymall.order.domain.model.OrderCancel;
import com.vogue.supplymall.order.domain.model.OrderItem;
import com.vogue.supplymall.order.domain.model.OrderItemProduct;
import com.vogue.supplymall.order.domain.model.OrderPayment;
import com.vogue.supplymall.order.domain.model.OrderSeller;
import com.vogue.supplymall.order.domain.model.OrderStatus;
import com.vogue.supplymall.order.domain.service.AccountPrepayDetailService;
import com.vogue.supplymall.order.domain.service.AccountPrepayService;
import com.vogue.supplymall.order.domain.service.OrderBuyerService;
import com.vogue.supplymall.order.domain.service.OrderCancelService;
import com.vogue.supplymall.order.domain.service.OrderItemProductService;
import com.vogue.supplymall.order.domain.service.OrderItemService;
import com.vogue.supplymall.order.domain.service.OrderPaymentService;
import com.vogue.supplymall.order.domain.service.OrderSellerService;
import com.vogue.supplymall.order.domain.service.OrderService;
import com.vogue.supplymall.order.domain.service.OrderStatusService;
import com.vogue.supplymall.order.exception.OrderIsTimeOverException;
import com.vogue.supplymall.order.exception.PayFailException;
import com.vogue.supplymall.order.exception.UpdateOrderException;
import com.vogue.supplymall.payment.api.WuXiangPayment;
import com.vogue.supplymall.payment.dto.BaseResultParameter;
import com.vogue.supplymall.payment.dto.BaseSimpleInputParameter;
import com.vogue.supplymall.payment.dto.CallbackInputParameter;
import com.vogue.supplymall.payment.dto.IResultParameter;
import com.vogue.supplymall.payment.dto.InputParameter;
import com.vogue.supplymall.payment.dto.InputParameterOrder;
import com.vogue.supplymall.payment.dto.InputParameterOrderItem;
import com.vogue.supplymall.payment.dto.PayQueryInputParameter;
import com.vogue.supplymall.payment.dto.PayQueryResultParameter;
import com.vogue.supplymall.payment.dto.PursePayInputParameter;
import com.vogue.supplymall.payment.dto.ResultParameter;
import com.vogue.supplymall.shop.domain.model.ProductAttrplan;
import com.vogue.supplymall.shop.domain.model.Shop;
import com.vogue.supplymall.shop.domain.service.ProductAttrplanService;
import com.vogue.supplymall.shop.domain.service.ShopService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

/**
 * The type Order update biz.
 *
 * @aouthor: zhangliang
 * @date: Create in 2018-02-07
 */
@Service("orderUpdateBiz")
public class OrderUpdateBizImpl implements OrderUpdateBiz {
    /**
     * The constant LOGGER_ORDERUPDATEBIZIMPL.
     */
    public static final Logger LOGGER_ORDERUPDATEBIZIMPL = LoggerFactory.getLogger(OrderUpdateBizImpl.class);

//    @Value("${pay.wuxiang.publickey}")
//    private String payWuxiangPublickey64 = null;

//    @Value("${pay.wuxiang.commPayCancelUrl}")
//    private String payWuxiangCommPayCancelUrl = null;

//    @Value("${pay.wuxiang.commPayGetUrl}")
//    private String payWuxiangCommPayGetUrl = null;

//    @Value("${pay.wuxiang.pursePayGetUrl}")
//    private String payWuxiangPursePayGetUrl = null;

//    @Value("${pay.wuxiang.callBack.secretKey}")
//    private String payWuxiangCallbackSecretKey = null;

//    @Value("${pay.wuxiang.stateQueryUrl}")
//    private String payWuxiangStateQueryUrl = null;

//    @Value("${pay.wuxiang.commPayCloseUrl}")
//    private String payWuxiangCommPayCloseUrl = null;

    @Resource
    private OrderService orderService;
    @Resource
    private OrderStatusService orderStatusService;
    @Resource
    private OrderPaymentService orderPaymentService;
    @Resource
    private ProductAttrplanService productAttrplanService;
    @Resource
    private OrderItemProductService orderItemProductService;
    @Resource
    private OrderCancelService orderCancelService;
    @Resource
    private OrderSellerService orderSellerService;
    @Resource
    private OrderItemService orderItemService;
    @Resource
    private AccountPrepayService accountPrepayService;
    @Resource
    private AccountPrepayDetailService accountPrepayDetailService;
    @Resource
    private ShopService shopService;
    @Resource
    private OrderBuyerService orderBuyerService;
    @Resource
    private MatchOrganService matchOrganService;
    /**
     * The Message source utils.
     */
    @Autowired
    protected MessageSourceUtils messageSourceUtils;
    @Resource
    private RefundBiz refundBiz;
    @DelegateResource
    private WuXiangPayment wuXiangPayment;
    @Resource(name = "memProvider")
    private IMemProvider<Object> memProvider;

    @Override
    @Transactional
    public Map<String, Object> updateFreight(OrderDetailInfo detailInfo, UserInfo userInfo) {
        if (1 == detailInfo.getBuyerSellerType()) {
            Order order = orderService.get(detailInfo.getOrderid());
            if (null == order) throw new UpdateOrderException("");
            OrderStatus orderStatus = orderStatusService.get(detailInfo.getStatusid());
            if (null == orderStatus) throw new UpdateOrderException("");
            if (orderStatus.getOrderstatus() > 0) throw new UpdateOrderException("");
            BigDecimal freight = new BigDecimal(detailInfo.getFreight());
            order.setFreight(freight);
            order.setFinalprice(order.getTotalprice().add(freight));
            order.setModifyDate(new Date());
            orderService.update(order);
            Map<String, Object> result = new HashMap<>();
            result.put("finalprice", order.getTotalprice().add(freight));
            return result;
        }
        throw new UpdateOrderException("");
    }

    @Override
    @Transactional
    public Boolean updateStatus(OrderDetailInfo detailInfo, UserInfo userInfo) {
        Order order = orderService.get(detailInfo.getOrderid());
        if (null == order) throw new UpdateOrderException("");
        OrderStatus status = orderStatusService.get(detailInfo.getStatusid());
        if (null == status) throw new UpdateOrderException("");
        /*订单状态check*/
        if (checkOrderStatus(detailInfo, status)) {
            throw new UpdateOrderException("");
        }
        // 2018/11/16 卖家已拉取，轻模式不能发货
        if (status.getPullstate() == 1 && detailInfo.getAction() == 3 && status.getOrderstatus() == 2) {
            throw new UpdateOrderException("");
        }
        /*更新订单状态*/
        status.setOrderstatus(status.getOrderstatus() + 1);
        status.setModifyDate(new Date());
        int count = orderStatusService.update(status);
        if (count <= 0) {
            throw new UpdateOrderException("");
        }
        // 如果订单已完成，并且有差异数量，就自动添加退货单
        if (status.getOrderstatus() == 4) {
            orderReceiving(order, status, userInfo);
        }
        return true;
    }

    @Override
    public void orderReceiving(Order order, OrderStatus status, UserInfo userInfo) {
        Map<String, Long> para = new HashMap<>();
        para.put("orderid", order.getId());
        List<OrderPayment> orderPayments = orderPaymentService.selectByWhr0("orderid = #{orderid} ", para);
        // 线下金额 例：30
        BigDecimal lineOffPrice = orderPayments.parallelStream().filter((oi) -> oi.getPaymentmode() == 0).map(OrderPayment::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        // 非线下金额=实付金额 例：70
        BigDecimal lineOnPrice = orderPayments.parallelStream().filter((oi) -> oi.getPaymentmode() != 0).map(OrderPayment::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        List<OrderItem> orderItems = orderItemService.selectByWhr0(" orderid = #{orderid}", para);
        // 计算所有的差异金额 例：40
        BigDecimal diffPrice = orderItems.parallelStream().map(OrderItem::getDiffmoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        // 应返还金额 例：10
        BigDecimal refundPrice = diffPrice.subtract(lineOffPrice);
        // 计算中差异金额
        BigDecimal diffPriceCalc = refundPrice;

        for (OrderItem orderItem : orderItems) {
            /**
             * 2018/11/16 有差异数量得情况
             * 退货单总要添加，但是金额0元的就不用返还了。
             */
            if (orderItem.getDiffcount().compareTo(BigDecimal.ZERO) > 0) {
                para.put("orderid", order.getId());
                para.put("orderitemid", orderItem.getId());
                String sql = "orderid = #{orderid} and orderitemid = #{orderitemid} and mainproductflag = 1";
                OrderItemProduct itemProduct = orderItemProductService.selectOneByWhr0(sql, para);
                AlterRefundInfo alterRefundInfo = new AlterRefundInfo();
                alterRefundInfo.setOrderid(order.getId());
                alterRefundInfo.setOiid(orderItem.getId());
                alterRefundInfo.setOipid(itemProduct.getId());
                alterRefundInfo.setCause(6);
                // 预付货款
                alterRefundInfo.setRefundway(0);
                alterRefundInfo.setRefundquantity(Double.valueOf(orderItem.getDiffcount().toString()).intValue());
                // 2018/10/12 退单价格为总价（差异单价x差异数量）
                BigDecimal amount = itemProduct.getPrice().multiply(orderItem.getDiffcount());
                alterRefundInfo.setRefundprice(amount.toString());
                if (diffPriceCalc.compareTo(BigDecimal.ZERO) > 0) {
                    alterRefundInfo.setRefundway(4);
                }
                // 添加退货单
                Long refundId = refundBiz.addRefund(alterRefundInfo, userInfo);

                // 差异金额退款
                if (orderItem.getDiffmoney().compareTo(BigDecimal.ZERO) > 0) {
                    // 计算中差异金额
                    diffPriceCalc = diffPriceCalc.subtract(amount);
                    // 如果差异金额大于线下金额
                    if (refundPrice.compareTo(BigDecimal.ZERO) > 0) {
                        // 如果应还金额大于计算中差异金额就进行退款
                        if (refundPrice.compareTo(diffPriceCalc) > 0) {
                            try {
                                refundBiz.returnPrepay(order.getId(), refundId, amount, userInfo);
                            } catch (UpdateOrderException ue) {
                                throw ue;
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 更新订单时的状态check
     * 待更新状态不能大于原状态
     *
     * @param detailInfo
     * @param status
     * @return boolean
     */
    private Boolean checkOrderStatus(OrderDetailInfo detailInfo, OrderStatus status) {
        return !detailInfo.getOrderstatus().equals(status.getOrderstatus())
                || (status.getOrderstatus() >= detailInfo.getAction());

    }

    @Override
    @Transactional
    public void orderPayOffline(OrderDetailInfo orderDetailInfo) {
        OrderStatus orderStatus = orderStatusService.get(orderDetailInfo.getStatusid());
        if (null == orderStatus) {
            throw new PayFailException("");
        }
        /*必须是待付款状态*/
        if (orderStatus.getOrderstatus() != 0) {
            throw new PayFailException("");
        }

        /*判断时候超时*/
        long modifyTime = orderStatus.getModifyDate().getTime();
        long currentTime = System.currentTimeMillis();
        if ((currentTime - modifyTime) > ConstantBean.PAY_FAILURE_TIME) {
            orderStatus.setIscancel(true);
            orderStatus.setModifyDate(new Date());
            orderStatusService.update(orderStatus);
            /*更新商品计划*/
            returnProductInventory(orderDetailInfo);
            throw new PayFailException("");
        }

        try {
            deleteAllPayment(orderStatus.getOrderid());
        } catch (Exception ex) {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单编号[{}]保存新支付记录前清空旧支付记录失败，原因：{}", orderStatus.getOrderid(), ex.getMessage());
            throw new PayFailException(ex.getMessage());
        }
        /*支付过的订单不能重复支付*/
//        if (payment.isPresent()) {
//            throw new PayFailException("");
//        }
        Order order = orderService.get(orderStatus.getOrderid());
        payOfflinePayment(orderDetailInfo, order.getFinalprice());

        saveOrderStateByShopWaitingOrder(orderStatus);
//        orderStatus.setOrderstatus(1);
//        orderStatus.setModifyDate(new Date());
//        orderStatusService.update(orderStatus);               
    }

    /**
     * 根据卖家店铺设置的是否手动接单标志来设置订单的状态
     *
     * @param orderStatus
     */
    public void saveOrderStateByShopWaitingOrder(OrderStatus orderStatus) {
        if (orderStatus == null || orderStatus.getOrderid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的参数为空 orderid");
        }
        OrderSeller os = orderSellerService.selectOneByWhr("orderid=" + orderStatus.getOrderid());
        if (os == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单id{}的orderSeller为空", orderStatus.getOrderid());
        }
        Shop shop = shopService.get(os.getShopid());
        if (shop == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单id{}的shop为空", orderStatus.getOrderid());
        } else {
            if (shop.getWaitingOrder()) {
                orderStatus.setOrderstatus(1);
            } else {
                orderStatus.setOrderstatus(2);
            }
            orderStatus.setModifyDate(new Date());
            orderStatusService.update(orderStatus);
        }
    }

    /**
     * 线下支付保存支付记录功能模块
     *
     * @param orderDetailInfo
     */
    private void payOfflinePayment(OrderDetailInfo orderDetailInfo, BigDecimal amount) {
//    	Optional<OrderPayment> payment = orderPaymentService.getForOrderId(orderDetailInfo.getOrderid());
//    	OrderPayment orderPayment = null;
//        if (payment.isPresent()) {
//        	orderPayment = payment.get();
//        	if(orderPayment.getPaymenttype() == EnumPaymentMode.UnderLine.getCode()) {
//        		//线下无操作
//        	}else {
//        		//线上操作先关闭交易订单
//        		orderPayClose(orderDetailInfo.getOrderid());
//        	}
//        }else {
//        	orderPayment = new OrderPayment();
//        } 
        if (orderDetailInfo.getOrderid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderDetailInfo必要的数据为空{}:{}"
                    , "orderid", orderDetailInfo.getOrderid());
        }
        if (amount == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:amount");
        }
        payOfflinePayment(orderDetailInfo.getOrderid(), amount);
    }

    public void payOfflinePayment(Long orderid, BigDecimal amount) {
        if (orderid == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderDetailInfo必要的数据为空{}:{}"
                    , "orderid", orderid);
        }
        if (amount == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:amount");
        }
        OrderPayment orderPayment = new OrderPayment();
        orderPayment.setAmount(amount);
        orderPayment.setArchivestatus(true);
        orderPayment.setOrderid(orderid);
        orderPayment.setPaymenttype(0);
        orderPayment.setPaymentmode(ConstantBean.EnumPaymentMode.UnderLine.getCode());
        orderPayment.setPaymentnumber("");
        orderPayment.setCancelstatus(false);
        orderPaymentService.save(orderPayment);
    }

    @Override
    @Transactional
    public void orderCancel(OrderDetailInfo orderDetailInfo) {
        LOGGER_ORDERUPDATEBIZIMPL.info(">>> 取消订单 >>>");
        if (orderDetailInfo.getStatusid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderDetailInfo必要的数据为空{}:{}"
                    , "statusid", orderDetailInfo.getStatusid());
        }
        OrderStatus orderStatus = orderStatusService.get(orderDetailInfo.getStatusid());
        // 2018/11/16 卖家已拉取（备货中）或者买家已拉取，不能取消
        if (orderStatus.getPullstate() == 1 || orderStatus.getBuypullstate() == 1) {
            throw new UpdateOrderException("");
        }
        if (!checkCancelPara(orderDetailInfo, orderStatus)) throw new UpdateOrderException("");
        if (orderStatus.getOrderstatus() < 2) {
            orderStatus.setIscancel(true);
            orderStatus.setModifyDate(new Date());
            orderStatusService.update(orderStatus);
            //撤销付款
            orderPayCancel(orderStatus);
        }
        OrderCancel cancel = orderCancelService.getOrderCancel(orderStatus.getOrderid());
        if (null == cancel || cancel.getCancelstate() == 3) {
            /*申请取消订单*/
            addOrderCancel(orderDetailInfo, orderStatus.getSyscodeid());
        }
        /*如果取消，更新商品计划*/
        if (orderStatus.getIscancel()) {
            returnProductInventory(orderDetailInfo);
        }
    }

    /**
     * 订单撤销付款
     *
     * @throws Exception
     */
    private void orderPayCancel(OrderStatus orderStatus) throws UpdateOrderException {
        orderPayCancel(orderStatus.getOrderid());
    }

    /**
     * 添加取消申请
     *
     * @param orderDetailInfo
     */
    private void addOrderCancel(OrderDetailInfo orderDetailInfo, Long syscodeid) {
        LOGGER_ORDERUPDATEBIZIMPL.info(">>> 插入取消申请 >>>");
        if (orderDetailInfo.getOrderid() == null || orderDetailInfo.getCancelcause() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderDetailInfo必要的数据为空{}:{} {}:{}"
                    , "orderid", orderDetailInfo.getOrderid()
                    , "cancelcause", orderDetailInfo.getCancelcause());
        }
        if (syscodeid == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:syscodeid");
        }
        OrderCancel orderCancel = new OrderCancel();
        orderCancel.setOrderid(orderDetailInfo.getOrderid());
        orderCancel.setCancelcause(orderDetailInfo.getCancelcause());
        orderCancel.setCancelstate(1);
        orderCancel.setSyscodeid(syscodeid);
        if (StringUtils.isEmpty(orderDetailInfo.getOthercauser())) {
            orderCancel.setOthercause("");
        } else {
            orderCancel.setOthercause(orderDetailInfo.getOthercauser());
        }
        orderCancelService.save(orderCancel);
    }

    /**
     * 更新商品计划
     *
     * @param orderDetailInfo
     */
    private void returnProductInventory(OrderDetailInfo orderDetailInfo) {
        LOGGER_ORDERUPDATEBIZIMPL.info(">>> 更新 >>>更新商品计划 >>> 返还库存");
        try {
            List<Map<String, Object>> mapList = orderItemProductService.findOrderProduct(orderDetailInfo);
            mapList.forEach((Map<String, Object> map) -> {
                ProductAttrplan attrplan = productAttrplanService.get(new Long(map.get("attrplanid").toString()));
                BigDecimal inv = attrplan.getInventory().add(new BigDecimal(map.get("itemquantity").toString()));
                attrplan.setInventory(inv);
                attrplan.setModifyDate(new Date());
                productAttrplanService.update(attrplan);
            });
        } catch (RuntimeException e) {
            throw new UpdateOrderException("");
        }
    }

    public void returnProductInventory(Long orderid) {
        OrderDetailInfo orderDetailInfo = new OrderDetailInfo();
        orderDetailInfo.setOrderid(orderid);
        returnProductInventory(orderDetailInfo);
    }

    /**
     * 取消订单时的状态check
     *
     * @param orderDetailInfo
     * @return boolean
     */
    private Boolean checkCancelPara(OrderDetailInfo orderDetailInfo, OrderStatus orderStatus) {
        if (orderDetailInfo.getBuyerSellerType() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderDetailInfo必要的数据为空{}:{}"
                    , "buyerSellerType", orderDetailInfo.getBuyerSellerType());
        }
        if (orderStatus.getOrderstatus() == null || orderStatus.getIscancel() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderStatus必要的数据为空{}:{} {}:{}"
                    , "orderstatus", orderStatus.getOrderstatus()
                    , "iscancel", orderStatus.getIscancel());
        }
        switch (orderDetailInfo.getBuyerSellerType()) {
            case 0:
                return (orderStatus.getOrderstatus() == 0
                        || orderStatus.getOrderstatus() == 1
                        || orderStatus.getOrderstatus() == 2)
                        && !orderStatus.getIscancel();
            case 1:
                return (orderStatus.getOrderstatus() == 1 || orderStatus.getOrderstatus() == 2)
                        && !orderStatus.getIscancel();
            default:
                return false;
        }
    }

    @Override
    @Transactional
    public void orderDelete(OrderDetailInfo orderDetailInfo) {
        LOGGER_ORDERUPDATEBIZIMPL.info(">>> 订单删除 >>>");
        if (orderDetailInfo.getStatusid() == null
                || orderDetailInfo.getOrderid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderDetailInfo必要的数据为空{}:{} {}:{}"
                    , "statusid", orderDetailInfo.getStatusid()
                    , "orderid", orderDetailInfo.getOrderid());
        }
        Order order = orderService.get(orderDetailInfo.getOrderid());
        if (order.getDisabledflag()) {
            throw new UpdateOrderException("");
        }
        OrderStatus orderStatus = orderStatusService.get(orderDetailInfo.getStatusid());
        long modifyTime = orderStatus.getModifyDate().getTime();
        long currentTime = System.currentTimeMillis();
        if ((currentTime - modifyTime) > ConstantBean.PAY_FAILURE_TIME) {
            orderStatus.setIscancel(true);
            orderStatus.setModifyDate(new Date());
            orderStatusService.update(orderStatus);
        }

        if (!orderStatus.getIscancel()) {
            throw new UpdateOrderException("");
        }

        order.setDisabledflag(true);
        order.setModifyDate(new Date());
        orderService.update(order);
        /*更新商品计划*/
        LOGGER_ORDERUPDATEBIZIMPL.info(">>> 更新商品计划 >>>");
        returnProductInventory(orderDetailInfo);
    }

    @Override
    @Transactional
    public void orderAgreeCancel(OrderDetailInfo orderDetailInfo) {
        if (orderDetailInfo.getStatusid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderDetailInfo必要的数据为空{}:{}"
                    , "statusid", orderDetailInfo.getStatusid());
        }
        OrderStatus orderStatus = orderStatusService.get(orderDetailInfo.getStatusid());
        if (!checkCancelPara(orderDetailInfo, orderStatus)) throw new UpdateOrderException("");
        if (orderDetailInfo.getIsAgreeCancel() != null && orderDetailInfo.getIsAgreeCancel()) {
            /*同意取消*/
            LOGGER_ORDERUPDATEBIZIMPL.info(">>> 同意取消订单 >>>");
            updateOrderCancel(orderDetailInfo, 2);
            orderStatus.setIscancel(true);
            orderStatus.setModifyDate(new Date());
            orderStatusService.update(orderStatus);
            //撤销付款
            orderPayCancel(orderStatus);
        } else {
            LOGGER_ORDERUPDATEBIZIMPL.info(">>> 拒绝取消订单 >>>");
            updateOrderCancel(orderDetailInfo, 3);
        }
        /*更新商品计划*/
        if (orderStatus.getIscancel()) {
            LOGGER_ORDERUPDATEBIZIMPL.info(">>> 更新商品计划 >>>");
            returnProductInventory(orderDetailInfo);
        }
    }

    /**
     * 添加取消申请
     *
     * @param orderDetailInfo
     */
    private void updateOrderCancel(OrderDetailInfo orderDetailInfo, Integer cancelStatus) {
        LOGGER_ORDERUPDATEBIZIMPL.info(">>> 更新取消申请 >>>");
        if (orderDetailInfo.getOrderid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderDetailInfo必要的数据为空{}:{}"
                    , "orderid", orderDetailInfo.getOrderid());
        }
        if (cancelStatus == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:cancelStatus");
        }
        OrderCancel orderCancel = orderCancelService.getOrderCancel(orderDetailInfo.getOrderid());
        if (null == orderCancel) {
            throw new UpdateOrderException("");
        }
        if (orderCancel.getCancelstate() > 1) {
            throw new UpdateOrderException("");
        }
        orderCancel.setCancelstate(cancelStatus);
        if (StringUtils.isEmpty(orderDetailInfo.getOthercauser())) {
            orderCancel.setOthercause("");
        } else {
            orderCancel.setOthercause(orderDetailInfo.getOthercauser());
        }
        orderCancel.setModifyDate(new Date());
        orderCancelService.update(orderCancel);
    }

    /**
     * 支付接口调用成功回调接口
     *
     * @param callbackInputParameter 回调接口的信息参数
     * @param callbackSecretKey      对接吾享支付接口支付成功回调密钥
     * @return
     */
    @Override
    @Transactional
    public Integer callBackFunction(CallbackInputParameter callbackInputParameter, String callbackSecretKey) {
        if (callbackInputParameter.getTradestate() == null
                || callbackInputParameter.getOrderid() == null
                || callbackInputParameter.getOrdfrom() == null
                || callbackInputParameter.getPaytypeid() == null
                || callbackInputParameter.getStoreid() == null
                || callbackInputParameter.getEndtime() == null
                || callbackInputParameter.getPayorderid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("callbackInputParameter必要的数据为空{}:{} {}:{} {}:{} {}:{} {}:{} {}:{} {}:{}"
                    , "tradestate", callbackInputParameter.getTradestate()
                    , "orderid", callbackInputParameter.getOrderid()
                    , "ordfrom", callbackInputParameter.getOrdfrom()
                    , "paytypeid", callbackInputParameter.getPaytypeid()
                    , "storeid", callbackInputParameter.getStoreid()
                    , "endtime", callbackInputParameter.getEndtime()
                    , "payorderid", callbackInputParameter.getPayorderid());
        }
        try {
            callbackInputParameter.validationProperty(callbackSecretKey);
            if ("0".equals(callbackInputParameter.getTradestate())) {
                Map<String, Object> params = new HashMap<>();
                params.put("ordernumber", callbackInputParameter.getOrderid());
                Order order = orderService.selectOneByWhr0("ordernumber=#{ordernumber}", params);
                if (order != null) {
                    // 订单状态
                    OrderStatus os = orderStatusService.selectOneByWhr("orderid=" + order.getId());
                    if (os == null) {
                        LOGGER_ORDERUPDATEBIZIMPL.error("没有对应的订单状态,订单编号:[{}]", callbackInputParameter.getOrderid());
                        throw new Exception(messageSourceUtils.getMessage("order.nopaymentinfo", new Object[]{callbackInputParameter.getOrderid()}));
                    } else {
                        LOGGER_ORDERUPDATEBIZIMPL.info("订单[{}]支付回调准备开始处理数据！", callbackInputParameter.getOrderid());
                        long current = System.currentTimeMillis();//当前时间毫秒数
                        long zero = current / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();//今天零点零分零秒的毫秒数

                        // 订单支付信息
                        List<OrderPayment> orderPaymentList = orderPaymentService.selectByWhr("orderid=" + order.getId());
                        /** 是否找到对应的支付记录 */
                        boolean isfindPayment = false;
                        /** 所有支付方式是否已全部支付完毕 */
                        boolean isDone = true;
                        int paymentmode = -1;
                        switch (callbackInputParameter.getPaytypeid()) {
                            case "6":
                                paymentmode = ConstantBean.EnumPaymentMode.WeChat.getCode();
                                break;
                            case "8":
                                paymentmode = ConstantBean.EnumPaymentMode.Alipay.getCode();
                                break;
                            case "20":
                                paymentmode = ConstantBean.EnumPaymentMode.WuXiang.getCode();
                                break;
                            default:
                                throw new Exception(messageSourceUtils.getMessage("order.wrong.paymode", new Object[]{callbackInputParameter.getPaytypeid()}));
                        }

                        if (os.getIscancel() || os.getOrderstatus() != 0
                                || (zero > order.getModifyDate().getTime() && zero - order.getModifyDate().getTime() >= ConstantBean.PAY_FAILURE_TIME.longValue())
                                || current - order.getModifyDate().getTime() >= ConstantBean.PAY_FAILURE_TIME.longValue()) {
                            LOGGER_ORDERUPDATEBIZIMPL.info("订单[{}]可能已经超时或者支付完成，支付回调准备开始退款！", callbackInputParameter.getOrderid());
                            //如果是已取消或者不是待付款状态，则赶快执行退款操作
                            LOGGER_ORDERUPDATEBIZIMPL.error("订单状态异常回刷支付状态失败，自动进行退款操作！订单编号[{}]，开始退款！", callbackInputParameter.getOrderid());
                            BaseSimpleInputParameter inputParameter = new BaseSimpleInputParameter();
                            inputParameter.setOrderid(callbackInputParameter.getOrderid());
                            inputParameter.setOrdfrom(Integer.parseInt(callbackInputParameter.getOrdfrom()));
                            inputParameter.setPaytypeid(Integer.parseInt(callbackInputParameter.getPaytypeid()));
                            inputParameter.setStoreid(callbackInputParameter.getStoreid());
                            LOGGER_ORDERUPDATEBIZIMPL.error("订单状态异常回刷支付状态失败，自动进行退款操作！订单编号[{}]，退款成功！", callbackInputParameter.getOrderid());
                            try {
                                //更新对应的支付记录状态
                                for (OrderPayment orderPayment : orderPaymentList) {
                                    if (orderPayment.getPaymentmode().intValue() == paymentmode) {
                                        orderPayCancelForWuxiang(inputParameter, orderPayment);
                                        break;
                                    }
                                }

                            } catch (Exception ex) {
                                LOGGER_ORDERUPDATEBIZIMPL.error(">>>>SOS<<<<:订单编号为[{}]的订单有一笔支付方式为{}金额为{}的付款退款失败，需要紧急处理！！！失败原因：{}",
                                        callbackInputParameter.getOrderid(),
                                        callbackInputParameter.getPayorderid(),
                                        callbackInputParameter.getMoney(),
                                        ex.getMessage());
                                throw ex;
                            }
                        } else {
                            LOGGER_ORDERUPDATEBIZIMPL.info("订单[{}]支付回调准备开始回置付款完成状态！", callbackInputParameter.getOrderid());

                            //更新对应的支付记录状态
                            for (OrderPayment orderPayment : orderPaymentList) {
                                if (orderPayment.getPaymentmode().intValue() == paymentmode) {
                                    if (callbackInputParameter.getEndtime() == null) {
                                        LOGGER_ORDERUPDATEBIZIMPL.error("更新支付记录状态失败：支付状态查询接口返回值缺少必要的属性endtime");
                                        throw new Exception("更新支付记录状态失败");
                                    }
                                    if (callbackInputParameter.getPayorderid() == null) {
                                        LOGGER_ORDERUPDATEBIZIMPL.error("更新支付记录状态失败：支付状态查询接口返回值缺少必要的属性payorderid");
                                        throw new Exception("更新支付记录状态失败");
                                    }
                                    isfindPayment = true;
                                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                    orderPayment.setArchivestatus(true);
                                    orderPayment.setPaymentdate(sdf.parse(callbackInputParameter.getEndtime()));
                                    orderPayment.setPaymentnumber(callbackInputParameter.getPayorderid());
                                    orderPayment.setModifyDate(new Date());
                                    orderPaymentService.update(orderPayment);
                                } else {
                                    if (!orderPayment.getArchivestatus()) {
                                        isDone = false;
                                        LOGGER_ORDERUPDATEBIZIMPL.error("支付方式为[{}]支付信息已经完成无法再操作,订单编号:[{}]", paymentmode, callbackInputParameter.getOrderid());
                                    }
                                }
                            }
                            //本次回写的支付方式找到操作完成，并且所有的支付方式都已经支付完成
                            if (isfindPayment) {
                                if (isDone) {
//                                  os.setOrderstatus(1);
//                                  os.setModifyDate(new Date());
//                                  orderStatusService.update(os);
                                    saveOrderStateByShopWaitingOrder(os);
                                    LOGGER_ORDERUPDATEBIZIMPL.info("订单[{}]支付回调完成了支付状态的设置！", callbackInputParameter.getOrderid());
                                }
                            } else {
                                LOGGER_ORDERUPDATEBIZIMPL.error("没有支付方式为[{}]支付信息,订单编号:[{}]", paymentmode, callbackInputParameter.getOrderid());
                                throw new Exception(messageSourceUtils.getMessage("order.fail.paymentinfo", null));
                            }
                        }
                    }
                } else {
                    LOGGER_ORDERUPDATEBIZIMPL.error("没有对应的订单信息,订单编号:[{}]", callbackInputParameter.getOrderid());
                    throw new Exception(messageSourceUtils.getMessage("order.noorderinfo.byordernumber", null));
                }
            } else {
                LOGGER_ORDERUPDATEBIZIMPL.error("订单编号[{}]支付失败", callbackInputParameter.getOrderid());
            }
            return 1;
        } catch (Exception ex) {
            throw new PayFailException(ex.getMessage());
        }
        
    }

    /**
     * 获取撤销付款的调用吾享接口所需的参数
     *
     * @param payment 支付记录对象
     * @return
     */
    private BaseSimpleInputParameter getInputParameterForPayCancel(OrderPayment payment) throws Exception {
        if (payment.getOrderid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("payment必要的数据为空{}:{}"
                    , "orderid", payment.getOrderid());
        }
        Order order = orderService.get(payment.getOrderid());
        if (order != null) {
            BaseSimpleInputParameter inputParameter = new BaseSimpleInputParameter();
            inputParameter.setOrderid(order.getOrdernumber());
            inputParameter.setOrdfrom(0);
            if (payment.getPaymentmode()
                    .intValue() == com.vogue.supplymall.common.constant.ConstantBean.EnumPaymentMode.Alipay.getCode()) {
                inputParameter.setPaytypeid(8);
            } else if (payment.getPaymentmode()
                    .intValue() == com.vogue.supplymall.common.constant.ConstantBean.EnumPaymentMode.WeChat.getCode()) {
                inputParameter.setPaytypeid(6);
            } else if (payment.getPaymentmode()
                    .intValue() == com.vogue.supplymall.common.constant.ConstantBean.EnumPaymentMode.WuXiang.getCode()) {
                inputParameter.setPaytypeid(20);
            } else {
                LOGGER_ORDERUPDATEBIZIMPL.error("错误的商城线上支付方式：{}", payment.getPaymentmode().intValue());
            }
            OrderSeller os = orderSellerService.selectOneByWhr("orderid=" + payment.getOrderid());
            inputParameter.setStoreid(os.getMcid());
            return inputParameter;
        } else {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单id为{}撤销付款失败：记录不存在", payment.getOrderid());
            throw new Exception(messageSourceUtils.getMessage("order.noorderinfo.byorderid", null));
        }
    }

    /**
     * 撤销订单付款接口
     *
     * @param orderid 订单id
     * @throws UpdateOrderException
     */
    @Override
    @Transactional
    public void orderPayCancel(Long orderid) throws UpdateOrderException {
        if (orderid == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:orderid");
        }
        try {
            List<OrderPayment> paymentList = orderPaymentService.selectByWhr("orderid=" + orderid);
            for (OrderPayment payment : paymentList) {
                if (!payment.getCancelstatus()) {
                    switch (payment.getPaymentmode()) {
                        case 0:
                            orderPayCancelForUnderline();
                            break;
                        case 1:
                        case 2:
                        case 3:
                            orderPayCancelForWuxiang(getInputParameterForPayCancel(payment), payment);
                            break;
                        case 4:
                            orderPayCancelForAdvance(payment.getOrderid());
                            break;
                        default:
                            throw new Exception(messageSourceUtils.getMessage("order.cancelpay.fail",
                                    new Object[]{payment.getPaymentmode()}));
                    }
                    payment.setModifyDate(new Date());
                    payment.setCancelstatus(true);
                    orderPaymentService.update(payment);
                }
            }
        } catch (Exception e) {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单id为{}撤销付款失败：{}", orderid, e.getMessage());
            throw new UpdateOrderException(e.getMessage());
        }
    }

    /**
     * 删除支付记录（线上的如果已支付则不允许支付）
     *
     * @param inputParameter
     * @throws Exception
     */
    private void deletePayment(BaseSimpleInputParameter inputParameter) throws Exception {
        if (inputParameter.getOrderid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("inputParameter必要的数据为空 :{}"
                    , "orderid");
        }
        if (inputParameter.getPaytypeid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("inputParameter必要的数据为空 :{}"
                    , "paytypeid");
        }
        if (inputParameter.getStoreid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("inputParameter必要的数据为空 :{}"
                    , "storeid");
        }
        try {
            InterCachePayValues cachedPayValues = null;
            if (Integer.parseInt(VestUtils.getEntryMode()) + Integer.parseInt(VestUtils.getPayTogether()) == 0) {
                cachedPayValues = (CachedPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_PAY_VALUES);
            } else {
                cachedPayValues = (CachedTsPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_TS_PAY_VALUES);
            }
            IResultParameter prp = null;
            try {
                String publickey64 = cachedPayValues.getPayWuxiangPublickey64();
                String url = cachedPayValues.getPayWuxiangStateQueryUrl();
                @SuppressWarnings("unchecked")
                FutureWrapper<IResultParameter> wrapper = FutureWrapper.wrapper( wuXiangPayment, gt -> {
                    try {
                        gt.queryPayState(inputParameter, url, publickey64);
                    } catch (Exception e) {
                        LOGGER_ORDERUPDATEBIZIMPL.error(e.getMessage());
                    }
                }, IResultParameter.class );
                prp = wrapper.get();
                if (prp == null) {
                    throw new Exception("远程调用查询订单状态接口异步调用返回结果为空");
                }
            } catch (Exception e) {
                LOGGER_ORDERUPDATEBIZIMPL.error("支付接口异常：{}", e.getMessage());
                throw new PayFailException(e.getMessage());
            }
//            IResultParameter prp = wuXiangPayment.queryPayState(inputParameter, cachedPayValues.getPayWuxiangStateQueryUrl(),
//                    cachedPayValues.getPayWuxiangPublickey64());
            LOGGER_ORDERUPDATEBIZIMPL.debug("订单【{}】状态查询结果prp返回值 {}:{} {}:{} {}:{} {}:{} {}:{}"
                    , inputParameter.getOrderid()
                    , "returnCode", prp.getReturnCode()
                    , "data", prp.getData()
                    , "data.trade_state", (prp.getData() != null ? ((PayQueryResultParameter) prp).getData().getTrade_state() : null)
                    , "errorCode", prp.getErrorCode()
                    , "errorText", prp.getErrorText());
            // 已支付的直接抛异常告诉用户已支付成功无法删除
            if (prp.getReturnCode() == 1 && ((PayQueryResultParameter) prp).getData().getTrade_state().equals("0")) {
                LOGGER_ORDERUPDATEBIZIMPL.error("订单编号为{}删除支付记录失败：线上付款已经支付成功", inputParameter.getOrderid());
                throw new Exception(messageSourceUtils.getMessage("order.deletepayed.fail", null));
            } else {// 未支付的做成关单
                if (prp.getReturnCode() != 1) {
                    LOGGER_ORDERUPDATEBIZIMPL.error("订单编号为{}查询状态失败：编号{} 原因{}", inputParameter.getOrderid(), prp.getErrorCode(), prp.getErrorText());
                    LOGGER_ORDERUPDATEBIZIMPL.error("订单编号为{}查询有错误！直接尝试关单处理！", inputParameter.getOrderid());
                }
                BaseResultParameter brp = null;
                try {
                    String publickey64 = cachedPayValues.getPayWuxiangPublickey64();
                    String url = cachedPayValues.getPayWuxiangCommPayCloseUrl();
                    @SuppressWarnings("unchecked")
                    FutureWrapper<BaseResultParameter> wrapper = FutureWrapper.wrapper( wuXiangPayment, gt -> {
                        try {
                            gt.commPayClose(inputParameter, url, publickey64);
                        } catch (Exception e) {
                            LOGGER_ORDERUPDATEBIZIMPL.error(e.getMessage());
                        }
                    }, BaseResultParameter.class );
                    brp = wrapper.get();
                    if (brp == null) {
                        throw new Exception("远程调用关单接口异步调用返回结果为空");
                    }
                } catch (Exception e) {
                    LOGGER_ORDERUPDATEBIZIMPL.error("支付接口异常：{}", e.getMessage());
                    throw new PayFailException(e.getMessage());
                }
//                BaseResultParameter brp = wuXiangPayment.commPayClose(inputParameter, cachedPayValues.getPayWuxiangCommPayCloseUrl(),
//                        cachedPayValues.getPayWuxiangPublickey64());
                LOGGER_ORDERUPDATEBIZIMPL.debug("订单【{}】关单结果brp返回值 {}:{} {}:{} {}:{}"
                        , inputParameter.getOrderid()
                        , "returnCode", brp.getReturnCode()
                        , "errorCode", brp.getErrorCode()
                        , "errorText", brp.getErrorText());
                if (brp.getReturnCode() == 1) {
                    LOGGER_ORDERUPDATEBIZIMPL.info("订单编号为{}关单成功！！！", inputParameter.getOrderid());
                } else {
                    LOGGER_ORDERUPDATEBIZIMPL.error("订单编号为{}关单失败：编号{} 原因{}", inputParameter.getOrderid(), brp.getErrorCode(), brp.getErrorText());
                    throw new Exception(messageSourceUtils.getMessage("order.cancelpay.fail",
                            new Object[]{brp.getErrorText()}));
                }
            }
        } catch (Exception ex) {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单[{}]撤销支付失败：{}", inputParameter.getOrderid(), ex.getMessage());
            throw ex;
        }
    }

    /**
     * 调用吾享接口的网上支付方式用此方法退款
     *
     * @param inputParameter 调用吾享接口需要的参数
     */
    private void orderPayCancelForWuxiang(BaseSimpleInputParameter inputParameter, OrderPayment orderPayment) throws Exception {
        if (inputParameter.getOrderid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("inputParameter必要的数据为空 :{}"
                    , "orderid");
        }
        if (inputParameter.getPaytypeid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("inputParameter必要的数据为空 :{}"
                    , "paytypeid");
        }
        if (inputParameter.getStoreid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("inputParameter必要的数据为空 :{}"
                    , "storeid");
        }
        try {
            InterCachePayValues cachedPayValues = null;
            if (orderPayment.getMergeflag() + orderPayment.getTsflag() == 0) {
                cachedPayValues = (CachedPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_PAY_VALUES);
            } else {
                cachedPayValues = (CachedTsPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_TS_PAY_VALUES);
            }
            IResultParameter prp = null;
            try {
                String publickey64 = cachedPayValues.getPayWuxiangPublickey64();
                String url = cachedPayValues.getPayWuxiangStateQueryUrl();
                @SuppressWarnings("unchecked")
                FutureWrapper<IResultParameter> wrapper = FutureWrapper.wrapper( wuXiangPayment, gt -> {
                    try {
                        gt.queryPayState(inputParameter, url, publickey64);
                    } catch (Exception e) {
                        LOGGER_ORDERUPDATEBIZIMPL.error(e.getMessage());
                    }
                }, IResultParameter.class );
                prp = wrapper.get();
                if (prp == null) {
                    throw new Exception("远程调用查询接口异步调用返回结果为空");
                }
            } catch (Exception e) {
                LOGGER_ORDERUPDATEBIZIMPL.error("支付接口异常：{}", e.getMessage());
                throw new PayFailException(e.getMessage());
            }
//            IResultParameter prp = wuXiangPayment.queryPayState(inputParameter, cachedPayValues.getPayWuxiangStateQueryUrl(),
//                    cachedPayValues.getPayWuxiangPublickey64());
            LOGGER_ORDERUPDATEBIZIMPL.debug("订单【{}】状态查询结果prp返回值 {}:{} {}:{} {}:{} {}:{} {}:{}"
                    , inputParameter.getOrderid()
                    , "returnCode", prp.getReturnCode()
                    , "data", prp.getData()
                    , "data.trade_state", (prp.getData() != null ? ((PayQueryResultParameter) prp).getData().getTrade_state() : null)
                    , "errorCode", prp.getErrorCode()
                    , "errorText", prp.getErrorText());
            // 已支付的做成撤销
            if (prp.getReturnCode() == 1 && prp.getData() != null && ((PayQueryResultParameter) prp).getData().getTrade_state().equals("0")) {
                
                BaseResultParameter crp = null;
                try {
                    String publickey64 = cachedPayValues.getPayWuxiangPublickey64();
                    String url = cachedPayValues.getPayWuxiangCommPayCancelUrl();
                    @SuppressWarnings("unchecked")
                    FutureWrapper<BaseResultParameter> wrapper = FutureWrapper.wrapper( wuXiangPayment, gt -> {
                        try {
                            gt.commPayCancel(inputParameter, url, publickey64);
                        } catch (Exception e) {
                            LOGGER_ORDERUPDATEBIZIMPL.error(e.getMessage());
                        }
                    }, BaseResultParameter.class );
                    crp = wrapper.get();
                    if (crp == null) {
                        throw new Exception("远程调用支付接口异步调用返回结果为空");
                    }
                } catch (Exception e) {
                    LOGGER_ORDERUPDATEBIZIMPL.error("支付接口异常：{}", e.getMessage());
                    throw new PayFailException(e.getMessage());
                }
                
//                BaseResultParameter crp = wuXiangPayment.commPayCancel(inputParameter,
//                        cachedPayValues.getPayWuxiangCommPayCancelUrl(), cachedPayValues.getPayWuxiangPublickey64());
                LOGGER_ORDERUPDATEBIZIMPL.debug("订单【{}】撤销付款结果crp返回值 {}:{} {}:{} {}:{}"
                        , inputParameter.getOrderid()
                        , "returnCode", crp.getReturnCode()
                        , "errorCode", crp.getErrorCode()
                        , "errorText", crp.getErrorText());
                if (crp.getReturnCode() == 1) {
                    LOGGER_ORDERUPDATEBIZIMPL.info("订单编号为{}撤销付款成功！！！", inputParameter.getOrderid());
                } else {
                    LOGGER_ORDERUPDATEBIZIMPL.error("订单编号为{}撤销付款失败：编号{} 原因{}", inputParameter.getOrderid(), crp.getErrorCode(), crp.getErrorText());
                    throw new Exception(messageSourceUtils.getMessage("order.cancelpay.fail",
                            new Object[]{crp.getErrorText()}));
                }
            } else {// 未支付的做成关单
                if (prp.getReturnCode() != 1) {
                    LOGGER_ORDERUPDATEBIZIMPL.error("订单编号为{}查询状态失败：编号{} 原因{}", inputParameter.getOrderid(), prp.getErrorCode(), prp.getErrorText());
                    LOGGER_ORDERUPDATEBIZIMPL.error("订单编号为{}查询有错误！直接尝试关单处理！", inputParameter.getOrderid());
                }
//				if(inputParameter.getPaytypeid() == 20) {
//					LOGGER_ORDERUPDATEBIZIMPL.info("订单[{}]支付方式为商龙云钱包无需关单操作", inputParameter.getOrderid());
//				}else {
                
                BaseResultParameter brp = null;
                try {
                    String publickey64 = cachedPayValues.getPayWuxiangPublickey64();
                    String url = cachedPayValues.getPayWuxiangCommPayCloseUrl();
                    @SuppressWarnings("unchecked")
                    FutureWrapper<BaseResultParameter> wrapper = FutureWrapper.wrapper( wuXiangPayment, gt -> {
                        try {
                            gt.commPayCancel(inputParameter, url, publickey64);
                        } catch (Exception e) {
                            LOGGER_ORDERUPDATEBIZIMPL.error(e.getMessage());
                        }
                    }, BaseResultParameter.class );
                    brp = wrapper.get();
                    if (brp == null) {
                        throw new Exception("远程调用关单接口异步调用返回结果为空");
                    }
                } catch (Exception e) {
                    LOGGER_ORDERUPDATEBIZIMPL.error("支付接口异常：{}", e.getMessage());
                    throw new PayFailException(e.getMessage());
                }
                
//                BaseResultParameter brp = wuXiangPayment.commPayClose(inputParameter, cachedPayValues.getPayWuxiangCommPayCloseUrl(),
//                        cachedPayValues.getPayWuxiangPublickey64());
                LOGGER_ORDERUPDATEBIZIMPL.debug("订单【{}】关单结果brp返回值 {}:{} {}:{} {}:{}"
                        , inputParameter.getOrderid()
                        , "returnCode", brp.getReturnCode()
                        , "errorCode", brp.getErrorCode()
                        , "errorText", brp.getErrorText());
                if (brp.getReturnCode() == 1) {
                    LOGGER_ORDERUPDATEBIZIMPL.info("订单编号为{}关单成功！！！", inputParameter.getOrderid());
                } else {
                    if ("406".equals(brp.getErrorCode())) {
                        LOGGER_ORDERUPDATEBIZIMPL.info("订单编号为{}不存在直接当作关单成功处理！！！", inputParameter.getOrderid());
                    } else {
                        LOGGER_ORDERUPDATEBIZIMPL.error("订单编号为{}关单失败：编号{} 原因{}", inputParameter.getOrderid(), brp.getErrorCode(), brp.getErrorText());
                        throw new Exception(messageSourceUtils.getMessage("order.cancelpay.fail",
                                new Object[]{brp.getErrorText()}));
                    }
                }
//				}				
            }
        } catch (Exception ex) {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单[{}]撤销支付失败：{}", inputParameter.getOrderid(), ex.getMessage());
            throw ex;
        }

    }

    /**
     * 预付款支付方式用此方法退款
     */
    private void orderPayCancelForAdvance(Long orderid) {
        if (orderid == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:orderid");
        }
        try {
            List<AccountPrepayDetail> accountPrepayDetailList = accountPrepayDetailService.selectByWhr("orderid=" + orderid);
            AccountPrepay accountPrepay = null;
            AccountPrepayDetail reutrnAccountPrepayDetail = null;//退款类型的支付明细
            for (AccountPrepayDetail accountPrepayDetail : accountPrepayDetailList) {
                if (accountPrepay == null) {
                    Map<String, Object> params = new HashMap<>();
                    params.put("sellsyscodeid", accountPrepayDetail.getSellsyscodeid());
                    params.put("sellorganid", accountPrepayDetail.getSellorganid());
                    params.put("buysyscodeid", accountPrepayDetail.getBuysyscodeid());
                    params.put("buyorganid", accountPrepayDetail.getBuyorganid());
                    accountPrepay = accountPrepayService.selectOneByWhr0(
                            "sellsyscodeid=#{sellsyscodeid} and sellorganid=#{sellorganid} and buysyscodeid=#{buysyscodeid} and buyorganid=#{buyorganid}", params);
                }
                accountPrepay.setBalance(accountPrepay.getBalance().add(accountPrepayDetail.getAmount()));
                reutrnAccountPrepayDetail = new AccountPrepayDetail();
                org.springframework.beans.BeanUtils.copyProperties(accountPrepayDetail, reutrnAccountPrepayDetail, "id", "tendid", "type", "createDate", "modifyDate");
                reutrnAccountPrepayDetail.setType(3);
                reutrnAccountPrepayDetail.setCreateDate(new Date());
                reutrnAccountPrepayDetail.setModifyDate(new Date());
                accountPrepayDetailService.save(reutrnAccountPrepayDetail);
                LOGGER_ORDERUPDATEBIZIMPL.info("订单id为{}的预付货款记录已撤销付款，撤销金额:{}", orderid, accountPrepayDetail.getAmount());
            }
            accountPrepayService.update(accountPrepay);
        } catch (Exception ex) {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单[{}]预付款退款失败：{}", orderid, ex.getMessage());
            throw ex;
        }
    }

    /**
     * 线下支付方式用此方法退款
     */
    private void orderPayCancelForUnderline() {
        //暂时没有业务处理...
    }

    /**
     * 关闭订单交易接口
     *
     * @param orderid
     * @throws UpdateOrderException
     */
    @Override
    public void orderPayClose(Long orderid) throws UpdateOrderException {
        if (orderid == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:orderid");
        }
        try {
            List<OrderPayment> paymentList = orderPaymentService.selectByWhr("orderid=" + orderid);
            for (OrderPayment payment : paymentList) {
                if (!payment.getCancelstatus() && !payment.getArchivestatus()) {
                    switch (payment.getPaymentmode()) {
                        case 0:
                            break;
                        case 1:
                        case 2:
                        case 3:
                            orderPayCloseForWuxiang(getInputParameterForPayCancel(payment), orderid);
                            break;
                        case 4:
                            break;
                        default:
                            throw new Exception(messageSourceUtils.getMessage("order.cancelpay.fail",
                                    new Object[]{payment.getPaymentmode()}));
                    }
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            LOGGER_ORDERUPDATEBIZIMPL.error("订单id为{}关单失败：{}", orderid, e.getMessage());
            throw new UpdateOrderException(e.getMessage());
        }
    }

    /**
     * 调用吾享接口的网上支付类型关单接口
     *
     * @param inputParameter
     * @param orderid
     * @throws Exception
     */
    private void orderPayCloseForWuxiang(BaseSimpleInputParameter inputParameter, Long orderid) throws Exception {
        if (orderid == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:orderid");
        }
        InterCachePayValues cachedPayValues = null;
        if (Integer.parseInt(VestUtils.getEntryMode()) + Integer.parseInt(VestUtils.getPayTogether()) == 0) {
            cachedPayValues = (CachedPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_PAY_VALUES);
        } else {
            cachedPayValues = (CachedTsPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_TS_PAY_VALUES);
        }
        IResultParameter prp = null;
        try {
            String publickey64 = cachedPayValues.getPayWuxiangPublickey64();
            String url = cachedPayValues.getPayWuxiangStateQueryUrl();
            @SuppressWarnings("unchecked")
            FutureWrapper<IResultParameter> wrapper = FutureWrapper.wrapper( wuXiangPayment, gt -> {
                try {
                    gt.queryPayState(inputParameter, url, publickey64);
                } catch (Exception e) {
                    LOGGER_ORDERUPDATEBIZIMPL.error(e.getMessage());
                }
            }, IResultParameter.class );
            prp = wrapper.get();
            if (prp == null) {
                throw new Exception("远程调用订单状态查询接口异步调用返回结果为空");
            }
        } catch (Exception e) {
            LOGGER_ORDERUPDATEBIZIMPL.error("支付接口异常：{}", e.getMessage());
            throw new PayFailException(e.getMessage());
        }
//        IResultParameter prp = wuXiangPayment.queryPayState(inputParameter, cachedPayValues.getPayWuxiangStateQueryUrl(),
//                cachedPayValues.getPayWuxiangPublickey64());
        LOGGER_ORDERUPDATEBIZIMPL.debug("订单【{}】状态查询结果prp返回值 {}:{} {}:{} {}:{} {}:{} {}:{}"
                , inputParameter.getOrderid()
                , "returnCode", prp.getReturnCode()
                , "data", prp.getData()
                , "data.trade_state", (prp.getData() != null ? ((PayQueryResultParameter) prp).getData().getTrade_state() : null)
                , "errorCode", prp.getErrorCode()
                , "errorText", prp.getErrorText());
        if (prp.getReturnCode() == 1) {
            // 已支付的做成撤销
            if (((PayQueryResultParameter) prp).getData().getTrade_state().equals("0")) {
                refreshOrderPayStatus(orderid);
                throw new Exception("订单已支付请刷新页面");
            } else {// 未支付的做成关单
                BaseResultParameter brp = null;
                try {
                    String publickey64 = cachedPayValues.getPayWuxiangPublickey64();
                    String url = cachedPayValues.getPayWuxiangCommPayCloseUrl();
                    @SuppressWarnings("unchecked")
                    FutureWrapper<BaseResultParameter> wrapper = FutureWrapper.wrapper( wuXiangPayment, gt -> {
                        try {
                            gt.commPayClose(inputParameter, url, publickey64);
                        } catch (Exception e) {
                            LOGGER_ORDERUPDATEBIZIMPL.error(e.getMessage());
                        }
                    }, BaseResultParameter.class );
                    brp = wrapper.get();
                    if (brp == null) {
                        throw new Exception("远程调用关单接口异步调用返回结果为空");
                    }
                } catch (Exception e) {
                    LOGGER_ORDERUPDATEBIZIMPL.error("支付接口异常：{}", e.getMessage());
                    throw new PayFailException(e.getMessage());
                }
                
//                BaseResultParameter brp = wuXiangPayment.commPayClose(inputParameter, cachedPayValues.getPayWuxiangCommPayCloseUrl(),
//                        cachedPayValues.getPayWuxiangPublickey64());
                if (brp.getReturnCode() == 1) {
                    LOGGER_ORDERUPDATEBIZIMPL.info("订单id为{}关单成功！！！", orderid);
                } else {
                    LOGGER_ORDERUPDATEBIZIMPL.error("订单id为{}关单失败：编号{} 原因{}", orderid, brp.getErrorCode(), brp.getErrorText());
                    throw new Exception(messageSourceUtils.getMessage("order.cancelpay.fail",
                            new Object[]{brp.getErrorText()}));
                }
            }
        } else {
            if (!prp.getErrorCode().equals("400")) {
                LOGGER_ORDERUPDATEBIZIMPL.error("订单id为{}查询状态失败：编号{} 原因{}", orderid, prp.getErrorCode(), prp.getErrorText());
                throw new Exception(prp.getErrorText());
            } else {
                LOGGER_ORDERUPDATEBIZIMPL.info("订单id为{}支付订单未生成直接关单成功处理！！！", orderid);
            }
        }
    }

    /**
     * 线上支付获取信息
     * orderid   订单id
     * paytypeid 支付方式id （5：闪惠 6：微信 7：百度钱包 8：支付宝 20：商龙云钱包）
     *
     * @param orderInfo
     * @return
     */
    @Override
    @Transactional
    public IResultParameter payOnline(OrderInfo orderInfo) {
        if (orderInfo.getOid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:orderid");
        }
        if (orderInfo.getPaytypeid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:paytypeid");
        }
        Order order = orderService.get(Long.parseLong(orderInfo.getOid()));
        try {
            try {
                deleteAllPayment(Long.parseLong(orderInfo.getOid()));
            } catch (Exception ex) {
                LOGGER_ORDERUPDATEBIZIMPL.error("订单id为[{}]保存新支付记录前清空旧支付记录失败，原因：{}", orderInfo.getOid(), ex.getMessage());
                throw ex;
            }
            if (order == null) {
                throw new PayFailException(messageSourceUtils.getMessage("order.noorderinfo.byordernumber", null));
            } else {
                OrderStatus orderStatus = orderStatusService.selectOneByWhr("orderid=" + Long.parseLong(orderInfo.getOid()));
                if (null == orderStatus) {
                    throw new PayFailException(messageSourceUtils.getMessage("order.noorderstatus",
                            new Object[]{orderInfo.getOid()}));
                }
                /* 必须是待付款状态 */
                if (orderStatus.getOrderstatus() != 0) {
                    throw new PayFailException(messageSourceUtils.getMessage("order.status.notwaitpay", null));
                }
                PayOnlinePaymentDTO dto = new PayOnlinePaymentDTO();
                dto.setAmount(order.getFinalprice());
                dto.setOrderid(Long.parseLong(orderInfo.getOid()));
                dto.setOrdernumber(order.getOrdernumber());
                dto.setPaytypeid(orderInfo.getPaytypeid());
                dto.setRedirectUrl(orderInfo.getRedirectUrl());
                IResultParameter rp = payOnlinePayment(dto);
                order.setModifyDate(new Date());
                orderService.update(order);
                return rp;
            }
        } catch (PayFailException e) {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单id为{}支付失败：{}", orderInfo.getOid(), e.getMessage());
            throw e;
        } catch (Exception e) {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单id为{}支付失败：{}", orderInfo.getOid(), e.getMessage());
            throw new PayFailException(e.getMessage());
        }
    }

    /**
     * 独立的线上支付方法（都走吾享支付接口的类型）
     * orderid     订单id
     * ordernumber 订单编号
     * paytypeid   线上支付类型 （5：闪惠 6：微信 7：百度钱包 8：支付宝）
     * amount      付款额度
     *
     * @param dto PayOnlinePaymentDTO
     * @return
     * @throws Exception
     */
    private IResultParameter payOnlinePayment(PayOnlinePaymentDTO dto) throws Exception {
        if (dto.getOrderid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:orderid");
        }
        if (dto.getOrdernumber() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:ordernumber");
        }
        if (dto.getPaytypeid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:paytypeid");
        } else {
            if (dto.getPaytypeid() == 20 && (dto.getRedirectUrl() == null || "".equals(dto.getRedirectUrl()))) {
                LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:redirectUrl");
            }
        }
        if (dto.getAmount() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:amount");
        }
        // 判断有没有支付记录
        OrderPayment payment = new OrderPayment();
        payment.setCreateDate(new Date());
        payment.setOrderid(dto.getOrderid());
        payment.setCancelstatus(false);
        payment.setPaymenttype(1);
        payment.setAmount(dto.getAmount());
        payment.setArchivestatus(false);
        payment.setModifyDate(new Date());
        payment.setPaymentnumber("");
        switch (dto.getPaytypeid().intValue()) {
            case 8:
                payment.setPaymentmode(ConstantBean.EnumPaymentMode.Alipay.getCode());
                break;
            case 6:
                payment.setPaymentmode(ConstantBean.EnumPaymentMode.WeChat.getCode());
                break;
            case 20:
                payment.setPaymentmode(ConstantBean.EnumPaymentMode.WuXiang.getCode());
                break;
            default:
                throw new Exception(messageSourceUtils.getMessage("order.invalid.onlinePaytype",
                        new Object[]{dto.getPaytypeid().intValue()}));
        }
        // 更新支付记录信息
        orderPaymentService.save(payment);

        // 拼数据调用支付接口
        List<OrderItem> oiList = orderItemService.selectByWhr("orderid=" + dto.getOrderid());
        List<OrderItemProduct> list = orderItemProductService.selectByWhr("orderid=" + dto.getOrderid());
        OrderSeller os = orderSellerService.selectOneByWhr("orderid=" + dto.getOrderid());
        if (StringUtils.isEmpty(os.getMcid())) {
            LOGGER_ORDERUPDATEBIZIMPL.error(">>>>Loss Seller Shop mcid!!!!");
            throw new PayFailException(messageSourceUtils.getMessage("order.wrong.lossmcid", null));
        }
        InputParameterOrder payDataInfo = new InputParameterOrder();
        payDataInfo.setBilldismoney(0.0);
        payDataInfo.setBillmoney(0.0);
        payDataInfo.setCardflag(0);
        payDataInfo.setDismoney(0.0);
        payDataInfo.setMoney(dto.getAmount().doubleValue());
        payDataInfo.setOrderid(dto.getOrdernumber());
        payDataInfo.setStoreid(os.getMcid());
        List<InputParameterOrderItem> payDataItemInfoList = new ArrayList<>();
        for (OrderItemProduct oip : list) {
            InputParameterOrderItem payDataItemInfo = new InputParameterOrderItem();
            payDataItemInfo.setItemid(String.valueOf(oip.getProductid()));
            payDataItemInfo.setItemname(oip.getPname());
            payDataItemInfo.setPrice(oip.getPrice().doubleValue());
            for (OrderItem oi : oiList) {
                if (oip.getOrderitemid().equals(oi.getId())) {
                    payDataItemInfo.setItemcount(oi.getItemquantity());
                }
            }
            payDataItemInfoList.add(payDataItemInfo);
        }
        payDataInfo.setItems(payDataItemInfoList);


        InterCachePayValues cachedPayValues = null;
        if (Integer.parseInt(VestUtils.getEntryMode()) + Integer.parseInt(VestUtils.getPayTogether()) == 0) {
            cachedPayValues = (CachedPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_PAY_VALUES);
        } else {
            cachedPayValues = (CachedTsPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_TS_PAY_VALUES);
        }

        IResultParameter rp = null;
        switch (dto.getPaytypeid()) {
            case 6:
            case 8:
                InputParameter inputParameter = new InputParameter();
                inputParameter.setData(payDataInfo);
                inputParameter.setPaytypeid(dto.getPaytypeid());
                
                try {
                    String publickey64 = cachedPayValues.getPayWuxiangPublickey64();
                    String url = cachedPayValues.getPayWuxiangCommPayGetUrl();
                    @SuppressWarnings("unchecked")
                    FutureWrapper<IResultParameter> wrapper = FutureWrapper.wrapper( wuXiangPayment, gt -> {
                        try {
                            gt.commPayGetUrl(inputParameter, url, publickey64);
                        } catch (Exception e) {
                            LOGGER_ORDERUPDATEBIZIMPL.error(e.getMessage());
                        }
                    }, IResultParameter.class );
                    rp = wrapper.get();
                    if (rp == null) {
                        throw new Exception("远程调用支付宝支付异步调用返回结果为空");
                    }
                } catch (Exception e) {
                    LOGGER_ORDERUPDATEBIZIMPL.error("支付接口异常：{}", e.getMessage());
                    throw new PayFailException(e.getMessage());
                }
                
//                rp = (IResultParameter) wuXiangPayment.commPayGetUrl(inputParameter, cachedPayValues.getPayWuxiangCommPayGetUrl(),
//                        cachedPayValues.getPayWuxiangPublickey64());
                break;
            case 20:
                OrderBuyer buyer = orderBuyerService.selectOneByWhr("orderid=" + os.getOrderid());
                MatchOrgan organ = matchOrganService.get(buyer.getOrganid());
                PursePayInputParameter purseInputParameter = new PursePayInputParameter();
                purseInputParameter.setMoney(dto.getAmount().doubleValue());
                purseInputParameter.setOrderid(dto.getOrdernumber());
                purseInputParameter.setStoreid(os.getMcid());
                purseInputParameter.setRedirectUrl(dto.getRedirectUrl());
                purseInputParameter.setPaystoreid(organ.getMcid());
                purseInputParameter.setClientIp(getClientIp());
                
                try {
                    String publickey64 = cachedPayValues.getPayWuxiangPublickey64();
                    String url = cachedPayValues.getPayWuxiangPursePayGetUrl();
                    @SuppressWarnings("unchecked")
                    FutureWrapper<IResultParameter> wrapper = FutureWrapper.wrapper( wuXiangPayment, gt -> {
                        try {
                            gt.pursePayGetUrl(purseInputParameter, url, publickey64);
                        } catch (Exception e) {
                            LOGGER_ORDERUPDATEBIZIMPL.error(e.getMessage());
                        }
                    }, IResultParameter.class );
                    rp = wrapper.get();
                    if (rp == null) {
                        throw new Exception("远程调用商龙云钱包支付异步调用返回结果为空");
                    }
                } catch (Exception e) {
                    LOGGER_ORDERUPDATEBIZIMPL.error("支付接口异常：{}", e.getMessage());
                    throw new PayFailException(e.getMessage());
                }
                
//                rp = (IResultParameter) wuXiangPayment.pursePayGetUrl(purseInputParameter, cachedPayValues.getPayWuxiangPursePayGetUrl(),
//                        cachedPayValues.getPayWuxiangPublickey64());
                break;
            default:
                throw new Exception(messageSourceUtils.getMessage("order.invalid.onlinePaytype",
                        new Object[]{dto.getPaytypeid().intValue()}));
        }
        if (rp.getReturnCode() == 1) {
            return rp;
        } else {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单id为{}支付失败：错误编码[{}] 错误信息[{}]", dto.getOrderid(), rp.getErrorCode(), rp.getErrorText());
            throw new Exception(rp.getErrorText());
        }

    }

    public IResultParameter payOnline(OrderInfo orderInfo, BigDecimal amount) throws Exception {
        if (orderInfo.getOid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderInfo必要的数据为空 {}:{}"
                    , "oid", orderInfo.getOid());
        }
        if (amount == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:amount");
        }
        Order order = orderService.get(Long.parseLong(orderInfo.getOid()));
        PayOnlinePaymentDTO dto = new PayOnlinePaymentDTO();
        dto.setAmount(amount);
        dto.setOrderid(order.getId());
        dto.setOrdernumber(order.getOrdernumber());
        dto.setPaytypeid(orderInfo.getPaytypeid());
        dto.setRedirectUrl(orderInfo.getRedirectUrl());
        return payOnlinePayment(dto);
    }

    /**
     * 待支付的订单查询下是否已经支付过并且成功如果是则刷新状态变成已付款
     *
     * @param orderid
     * @return 返回订单最新状态 0:待付款 1:已付款
     */
    @Override
    @Transactional
    public Integer refreshOrderPayStatus(Long orderid) throws Exception {
        if (orderid == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:orderid");
        }
        List<OrderPayment> paymentList = orderPaymentService.selectByWhr("orderid=" + orderid);
        OrderSeller orderSeller = orderSellerService.selectOneByWhr("orderid=" + orderid);
        Order order = orderService.get(orderid);
        int result = paymentList != null && paymentList.size() > 0 ? 1 : 0;
        for (OrderPayment payment : paymentList) {
            if (payment.getCancelstatus()) {
                continue;
            } else {
                if (!payment.getArchivestatus()) {
                    PayQueryInputParameter payQueryInputParameter = new PayQueryInputParameter();
                    payQueryInputParameter.setOrdfrom(0);
                    payQueryInputParameter.setStoreid(orderSeller.getMcid());
                    payQueryInputParameter.setOrderid(order.getOrdernumber());
                    switch (payment.getPaymentmode()) {
                        case 1:
                            payQueryInputParameter.setPaytypeid(20);
                            break;
                        case 2:
                            payQueryInputParameter.setPaytypeid(6);
                            break;
                        case 3:
                            payQueryInputParameter.setPaytypeid(8);
                            break;
                        default:
                            payQueryInputParameter.setPaytypeid(0);
                            break;
                    }
                    if (payQueryInputParameter.getPaytypeid() > 0) {
                        result *= refreshOrderPayStatusByWuxiang(payQueryInputParameter, payment);
                    }
                }
            }
        }
        return result;
    }

    /**
     * 使用吾享支接口支付方式，同步订单最新状态方法
     *
     * @param payQueryInputParameter orderid
     * @return
     * @throws Exception
     */
    private Integer refreshOrderPayStatusByWuxiang(PayQueryInputParameter payQueryInputParameter, OrderPayment payment) throws Exception {
        if (payQueryInputParameter.getOrderid() == null
                || payQueryInputParameter.getOrdfrom() == null
                || payQueryInputParameter.getPaytypeid() == null
                || payQueryInputParameter.getStoreid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("payQueryInputParameter必要的数据为空 {}:{} {}:{} {}:{} {}:{}"
                    , "orderid", payQueryInputParameter.getOrderid()
                    , "ordfrom", payQueryInputParameter.getOrdfrom()
                    , "paytypeid", payQueryInputParameter.getPaytypeid()
                    , "storeid", payQueryInputParameter.getStoreid());
        }
        InterCachePayValues cachedPayValues = null;
        if (payment.getMergeflag() + payment.getTsflag() == 0) {
            cachedPayValues = (CachedPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_PAY_VALUES);
        } else {
            cachedPayValues = (CachedTsPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_TS_PAY_VALUES);
        }
        IResultParameter payQueryResultParameter = null;
        try {
            String publickey64 = cachedPayValues.getPayWuxiangPublickey64();
            String url = cachedPayValues.getPayWuxiangStateQueryUrl();
            @SuppressWarnings("unchecked")
            FutureWrapper<IResultParameter> wrapper = FutureWrapper.wrapper( wuXiangPayment, gt -> {
                try {
                    gt.queryPayState(payQueryInputParameter, url, publickey64);
                } catch (Exception e) {
                    LOGGER_ORDERUPDATEBIZIMPL.error(e.getMessage());
                }
            }, IResultParameter.class );
            payQueryResultParameter = wrapper.get();
            if (payQueryResultParameter == null) {
                throw new Exception("远程调用订单状态查询接口异步调用返回结果为空");
            }
        } catch (Exception e) {
            LOGGER_ORDERUPDATEBIZIMPL.error("支付接口异常：{}", e.getMessage());
            throw new PayFailException(e.getMessage());
        }
        
//        IResultParameter payQueryResultParameter = wuXiangPayment.queryPayState(payQueryInputParameter,
//                cachedPayValues.getPayWuxiangStateQueryUrl(), cachedPayValues.getPayWuxiangPublickey64());
        if (payQueryResultParameter.getReturnCode() == 1 && payQueryResultParameter.getData() != null
                && ((PayQueryResultParameter) payQueryResultParameter).getData().getTrade_state().equals("0")) {
            CallbackInputParameter callbackInputParameter = new CallbackInputParameter();
            callbackInputParameter.setOrderid(payQueryInputParameter.getOrderid());
            callbackInputParameter.setOrdfrom(payQueryInputParameter.getOrdfrom().toString());
            callbackInputParameter.setPaytypeid(payQueryInputParameter.getPaytypeid().toString());
            callbackInputParameter.setStoreid(payQueryInputParameter.getStoreid());
            callbackInputParameter.setTradestate("0");
            callbackInputParameter.setEndtime(((PayQueryResultParameter) payQueryResultParameter).getData().getTime_end());
            callbackInputParameter.setMoney(String.valueOf(((PayQueryResultParameter) payQueryResultParameter).getData().getTotal_money()));
            if (((PayQueryResultParameter) payQueryResultParameter).getData().getPayorderInfo() == null) {
                LOGGER_ORDERUPDATEBIZIMPL.error("查询支付结果订单信息payorderInfo数据为空无法刷新订单支付状态");
                throw new Exception("查询支付结果订单信息payorderInfo数据为空无法刷新订单支付状态");
            } else {
                callbackInputParameter.setPayorderid(((PayQueryResultParameter) payQueryResultParameter).getData().getPayorderInfo().getOrderpayid());
                callbackInputParameter.setWxorderid(((PayQueryResultParameter) payQueryResultParameter).getData().getPayorderInfo().getOrderid());
            }
            callbackInputParameter
                    .setSign(callbackInputParameter.getValidationPropertyStr(cachedPayValues.getPayWuxiangCallbackSecretKey()));
            callBackFunction(callbackInputParameter, cachedPayValues.getPayWuxiangCallbackSecretKey());
            return 1;
        } else {
            return 0;
        }
    }

    /**
     * 预付货款支付
     *
     * @param orderInfo 订单信息
     */
    @Override
    @Transactional
    public void payAdvance(OrderInfo orderInfo) {
        if (orderInfo.getOid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderInfo必要的数据为空 {}:{}"
                    , "oid", orderInfo.getOid());
        }
        try {
            deleteAllPayment(Long.parseLong(orderInfo.getOid()));
        } catch (Exception ex) {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单编号[{}]保存新支付记录前清空旧支付记录失败，原因：{}", orderInfo.getOid(), ex.getMessage());
            throw new PayFailException(ex.getMessage());
        }
        Order order = orderService.get(Long.parseLong(orderInfo.getOid()));
        saveOrderStateByShopWaitingOrder(payAdvance(orderInfo, order.getFinalprice()));
    }

    /**
     * 预付货款支付
     *
     * @param orderInfo 订单信息
     * @param amount    支付金额（自己指定）
     */
    public OrderStatus payAdvance(OrderInfo orderInfo, BigDecimal amount) {
        if (orderInfo.getOid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderInfo必要的数据为空 {}:{}"
                    , "oid", orderInfo.getOid());
        }
        OrderStatus orderStatus = orderStatusService.selectOneByWhr("orderid=" + orderInfo.getOid());
        if (null == orderStatus) {
            throw new PayFailException(messageSourceUtils.getMessage("order.noorderstatus",
                    new Object[]{orderInfo.getOid()}));
        }
        /* 必须是待付款状态 */
        if (orderStatus.getOrderstatus() != 0) {
            throw new PayFailException(messageSourceUtils.getMessage("order.status.notwaitpay", null));
        }
        Order order = orderService.get(Long.parseLong(orderInfo.getOid()));
        if (order == null) {
            throw new PayFailException(messageSourceUtils.getMessage("order.noorderinfo.byorderid", null));
        } else {
            OrderSeller orderSeller = orderSellerService.selectOneByWhr("orderid=" + order.getId());
            if (orderSeller == null) {
                throw new PayFailException(messageSourceUtils.getMessage("order.wrong.lossseller", null));
            } else {
                orderInfo.setShopOrganId(orderSeller.getOrganid());
            }
            payAdvancePayment(orderInfo, amount);
        }
        order.setModifyDate(new Date());
        orderService.update(order);
        return orderStatus;
    }

    /**
     * 预付货款指定金额付款
     *
     * @param orderInfo
     * @param amount
     */
    private void payAdvancePayment(OrderInfo orderInfo, BigDecimal amount) {
        if (orderInfo.getOid() == null
                || orderInfo.getShopOrganId() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderInfo必要的数据为空 {}:{} {}:{}"
                    , "oid", orderInfo.getOid()
                    , "shopOrganId", orderInfo.getShopOrganId());
        }
        if (amount == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:amount");
        }
        // 1.查当前买家对应卖家可用余额
        UserInfo info = (UserInfo) SecurityUtils.getSubject().getPrincipal();
        Map<String, Object> params = new HashMap<>();
        params.put("buysyscodeid", info.getSyscodeid());
        params.put("buyorganid", info.getOrganInfo() == null ? 0L : info.getOrganInfo().getId());
        params.put("sellorganid", orderInfo.getShopOrganId());
        AccountPrepay ap = accountPrepayService.selectOneByWhr0(
                "buysyscodeid=#{buysyscodeid} and buyorganid=#{buyorganid} and sellorganid=#{sellorganid}", params);
        if (ap == null || ap.getBalance().compareTo(amount) == -1) {
            throw new PayFailException(messageSourceUtils.getMessage("order.pay.fail.amountless", null));
        }
        // 2.插入一条支付明细
        AccountPrepayDetail apd = new AccountPrepayDetail();
        apd.setMemo("");
        apd.setOrderid(Long.parseLong(orderInfo.getOid()));
        apd.setAccountid(ap.getAccountid());
        apd.setSellsyscodeid(ap.getSellsyscodeid());
        apd.setSellorganid(ap.getSellorganid());
        apd.setSellmatchid(ap.getSellmatchid());
        apd.setBuysyscodeid(ap.getBuysyscodeid());
        apd.setBuyorganid(ap.getBuyorganid());
        apd.setBuymatchid(ap.getBuymatchid());
        Date now = new Date();
        apd.setCreateDate(now);
        apd.setCreateDate(now);
        apd.setAmount(amount);
        apd.setType(1);
        apd.setOrigin(2);
        accountPrepayDetailService.save(apd);
        // 3.更新预付款余额字段
        params = new HashMap<>();
        params.put("balance", ap.getBalance().subtract(apd.getAmount()));
        params.put("id", ap.getId());
        params.put("oldbalance", ap.getBalance());
        int count = accountPrepayService.update0(
                "update account_prepay set balance= #{balance} where id=#{id} and balance=#{oldbalance}", params);

        if (count == 0) {
            throw new PayFailException("账户信息不同步");
        }

        OrderPayment payment = new OrderPayment();
        payment.setOrderid(Long.parseLong(orderInfo.getOid()));
        payment.setCreateDate(now);
        payment.setCancelstatus(false);
        payment.setPaymenttype(1);
        payment.setAmount(amount);
        payment.setArchivestatus(true);
        payment.setModifyDate(now);
        payment.setPaymentnumber("");
        payment.setPaymentdate(now);
        payment.setPaymentmode(ConstantBean.EnumPaymentMode.AdvancePayment.getCode());
        // 更新支付记录信息
        orderPaymentService.save(payment);
    }

    /**
     * 组合方式支付
     */
    @Override
    @Transactional
    public IResultParameter payCombinationPayment(OrderInfo orderInfo, OrderDetailInfo orderDetailInfo) {
        if (orderInfo.getOid() == null
                || orderInfo.getPaymentList() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderInfo必要的数据为空 {}:{} {}:{}"
                    , "oid", orderInfo.getOid()
                    , "paymentList", orderInfo.getPaymentList());
        }
        boolean isContainingPayOnline = false;//查看是否包含支付状态延迟处理的线上支付方式
        Order order = orderService.get(Long.parseLong(orderInfo.getOid()));
        if (order == null) {
            throw new PayFailException(messageSourceUtils.getMessage("order.noorderinfo.byorderid", null));
        }
        OrderStatus orderStatus = orderStatusService.selectOneByWhr("orderid=" + orderInfo.getOid());
        if (null == orderStatus) {
            throw new PayFailException(messageSourceUtils.getMessage("order.noorderstatus",
                    new Object[]{orderInfo.getOid()}));
        }
        /* 必须是待付款状态 */
        if (orderStatus.getOrderstatus() != 0) {
            throw new PayFailException(messageSourceUtils.getMessage("order.status.notwaitpay", null));
        }

        try {
            deleteAllPayment(order.getId());
        } catch (Exception ex) {
            LOGGER_ORDERUPDATEBIZIMPL.error("订单编号[{}]保存新支付记录前清空旧支付记录失败，原因：{}", order.getId(), ex.getMessage());
            throw new PayFailException(ex.getMessage());
        }

        IResultParameter rp = new ResultParameter();
        List<PaymentInfo> paymentList = orderInfo.getPaymentList();
        for (PaymentInfo pi : paymentList) {
            switch (pi.getPaymentMode()) {
                case 0:
                    payOfflinePayment(orderDetailInfo, pi.getMoney());
                    break;
                case 1:
                case 2:
                case 3:
                    try {
                        switch (pi.getPaymentMode()) {
                            case 1:
                                orderInfo.setPaytypeid(20);
                                break;
                            case 2:
                                orderInfo.setPaytypeid(6);
                                break;
                            case 3:
                                orderInfo.setPaytypeid(8);
                                break;
                            default:
                                break;
                        }
                        orderInfo.setRedirectUrl(pi.getRedirectUrl());
                        rp = this.payOnline(orderInfo, pi.getMoney());
                        if (rp.getReturnCode() == 1) {
                            //正常
                        } else {
                            LOGGER_ORDERUPDATEBIZIMPL.error("订单id为{}支付失败：错误编码[{}] 错误信息[{}]", orderInfo.getOid(), rp.getErrorCode(), rp.getErrorText());
                            throw new Exception(rp.getErrorText());
                        }
                    } catch (Exception e) {
                        LOGGER_ORDERUPDATEBIZIMPL.error("订单id为{}支付失败：{}", orderInfo.getOid(), e.getMessage());
                        throw new PayFailException(e.getMessage());
                    }
                    isContainingPayOnline = true;
                    break;
                case 4:
                    payAdvancePayment(orderInfo, pi.getMoney());
                    break;
                default:
                    LOGGER_ORDERUPDATEBIZIMPL.error("组合支付无效的支付方式{}", pi.getPaymentMode());
                    throw new PayFailException(messageSourceUtils.getMessage("order.cancelpay.fail",
                            new Object[]{pi.getPaymentMode()}));
            }
        }

        Date now = new Date();
        if (!isContainingPayOnline) {
//			orderStatus.setOrderstatus(1);
//	        orderStatus.setModifyDate(now);
//	        orderStatusService.update(orderStatus);
            saveOrderStateByShopWaitingOrder(orderStatus);
        }
        //更新订单修改时间
        order.setModifyDate(now);
        orderService.update(order);
        return rp;
    }

    /**
     * 删除所有的支付方式(每次重新选择支付方式时候都把上一次选的清空，因为存在组合方式和单一支付方式来回切换的可能)
     *
     * @param orderid
     * @throws Exception
     */
    public void deleteAllPayment(Long orderid) throws Exception {
        if (orderid == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("必要的数据为空:orderid");
        }
        try {
            List<OrderPayment> paymentList = orderPaymentService.selectByWhr("orderid=" + orderid);
            for (OrderPayment payment : paymentList) {
                if (payment.getPaymenttype() == 1) {
                    switch (payment.getPaymentmode()) {
                        case 1:
                        case 2:
                        case 3:
                            orderPayCancelForWuxiang(this.getInputParameterForPayCancel(payment), payment);
                            break;
                        case 4:
                            orderPayCancelForAdvance(orderid);
                            break;
                        default:
                            break;
                    }
                }
                orderPaymentService.delete(payment.getId());
            }
        } catch (Exception ex) {
            LOGGER_ORDERUPDATEBIZIMPL.error("删除订单的所有支付方式失败[订单号{}]：{}", orderid, ex.getMessage());
            throw ex;
        }
    }

    @Override
    public void payAdvanceTs(OrderInfo orderInfo) {
        if (orderInfo.getOid() == null) {
            LOGGER_ORDERUPDATEBIZIMPL.error("orderInfo必要的数据为空 {}:{}"
                    , "oid", orderInfo.getOid());
        }
        OrderStatus orderStatus = orderStatusService.selectOneByWhr("orderid=" + orderInfo.getOid());
        if (null == orderStatus) {
            throw new PayFailException(messageSourceUtils.getMessage("order.noorderstatus",
                    new Object[]{orderInfo.getOid()}));
        }
        /* 必须是待付款状态 */
        if (orderStatus.getOrderstatus() != 0) {
            throw new PayFailException(messageSourceUtils.getMessage("order.status.notwaitpay", null));
        }
        Order order = orderService.get(Long.parseLong(orderInfo.getOid()));
        if (order == null) {
            throw new PayFailException(messageSourceUtils.getMessage("order.noorderinfo.byorderid", null));
        } else {
            OrderSeller orderSeller = orderSellerService.selectOneByWhr("orderid=" + order.getId());
            if (orderSeller == null) {
                throw new PayFailException(messageSourceUtils.getMessage("order.wrong.lossseller", null));
            } else {
                orderInfo.setShopOrganId(orderSeller.getOrganid());
            }
            payAdvancePayment(orderInfo, order.getFinalprice());
        }

        Date now = new Date();
        saveOrderStateByShopWaitingOrder(orderStatus);

        order.setModifyDate(now);
        orderService.update(order);
    }

    /**
     * 获取客户端ip地址
     *
     * @return 客户端ip地址
     */
    private String getClientIp() {
        return "114.114.114.114";
    }
}
